Popular Searches
Popular Course Categories
Popular Courses

Securing REST APIs Using Spring Security

Securing REST APIs Using Spring Security

Spring Security and Secure REST APIs

Securing REST APIs Using Spring Security

Course: Advance Java Training

Topic: Securing REST APIs Using Spring Security

Course Link: Advance Java Training Course

Demo Link: Register for a Course Demo

Website: JustAcademy


1. Introduction to REST API Security

A REST API allows applications to communicate over HTTP using methods such as GET, POST, PUT, PATCH, and DELETE. REST APIs are commonly used by web applications, mobile applications, microservices, and third-party integrations.

Because REST APIs can expose sensitive information and business operations, they must be protected against unauthorized access, credential theft, malicious requests, and data manipulation. Spring Security provides a comprehensive framework for implementing authentication, authorization, and other security controls in Spring Boot applications.

Securing a REST API means ensuring that only appropriate clients and users can access resources and perform permitted operations. For example, a customer may view their own orders, while an administrator may manage products and user accounts.

Why Is REST API Security Important?

  • Prevents unauthorized users from accessing protected endpoints.
  • Protects confidential information and personal data.
  • Restricts sensitive operations according to roles and permissions.
  • Helps defend against common web application attacks.
  • Supports secure communication between frontend and backend systems.
  • Provides consistent authentication and authorization policies.
  • Helps maintain data integrity and application reliability.

2. Learning Objectives

After studying this topic, learners should be able to:

  • Understand the fundamentals of REST API security.
  • Configure Spring Security in a Spring Boot application.
  • Secure endpoints using request authorization rules.
  • Differentiate authentication from authorization.
  • Configure HTTP Basic authentication for learning and testing.
  • Understand JWT and OAuth 2.0 Bearer token authentication.
  • Implement role-based access control.
  • Understand CSRF, CORS, password hashing, and security headers.
  • Handle unauthorized and forbidden requests appropriately.
  • Test secured REST endpoints using automated tests and API tools.

3. Understanding Authentication and Authorization

Authentication and authorization are two fundamental parts of API security. They work together but solve different problems.

Feature Authentication Authorization
Purpose Verifies the identity of a user or client. Determines which resources or actions are permitted.
Question answered Who are you? What are you allowed to do?
Example Validating a password or access token. Checking whether a user has the ADMIN role.
Spring Security concepts AuthenticationManager, AuthenticationProvider. Authorization rules, roles, authorities.

For example, a user may successfully authenticate with a valid access token but still be denied access to an administrator-only endpoint. Authentication establishes identity; authorization determines access.

4. Common Security Threats for REST APIs

4.1 Unauthorized Access

Unauthorized access occurs when an API allows a user to access data or functionality without sufficient authentication or permission checks.

Prevention: Require authentication for protected endpoints and apply authorization rules to sensitive operations.

4.2 Broken Access Control

Broken access control occurs when users can access resources or perform operations outside their permitted scope. For example, changing an order ID in a request might expose another customer's order.

Prevention: Check both user permissions and resource ownership on the server. Authentication alone does not prove that a resource belongs to the current user.

4.3 Credential Exposure

Credentials may be exposed through insecure connections, application logs, source code, or incorrectly configured storage.

Prevention: Use HTTPS, securely store credentials, avoid logging secrets, and rotate compromised credentials promptly.

4.4 Cross-Site Request Forgery (CSRF)

CSRF can cause a browser to send an unwanted authenticated request to an application where the browser automatically attaches credentials, such as session cookies.

Prevention: Retain appropriate CSRF protection for cookie-based authentication. Disabling CSRF should be a deliberate decision based on the application's authentication model and deployment architecture.

4.5 Cross-Origin Resource Sharing (CORS) Misconfiguration

CORS controls which browser origins may read responses from an API. An overly permissive policy can expose data to untrusted websites when other security conditions permit access.

Prevention: Allow only the required origins, methods, and headers. CORS is not a replacement for authentication or authorization.

4.6 Injection and Invalid Input

Malicious or malformed input can exploit weaknesses in database queries, data binding, or business logic.

Prevention: Validate input, use parameterized database queries, enforce constraints, and avoid constructing database queries through unsafe string concatenation.

5. Spring Security Architecture for REST APIs

Spring Security integrates with the servlet request-processing pipeline through security filters. Before a protected request reaches a controller, the configured filter chain can process authentication, security context management, authorization, and other security checks.

Typical Request Flow

  1. A client sends an HTTP request to the REST API.
  2. The request passes through the servlet filter chain.
  3. Spring Security processes the configured security filters.
  4. The configured authentication mechanism validates the credentials or access token.
  5. The authenticated identity and authorities become available to security components.
  6. Authorization rules determine whether the request is permitted.
  7. If permitted, the request reaches the controller and application service.
  8. The application returns an HTTP response to the client.

If authentication fails or access is denied, the request is handled by the configured security exception-handling mechanism rather than being allowed to perform the protected operation.

Important Spring Security Components

Component Purpose
SecurityFilterChain Defines security filters and request security configuration.
AuthenticationManager Coordinates authentication when that authentication flow uses it.
AuthenticationProvider Performs a particular type of authentication.
UserDetailsService Loads user details for username-and-password authentication.
PasswordEncoder Encodes and verifies stored password hashes.
SecurityContext Holds the current security authentication information.
AuthorizationManager Evaluates whether a request or invocation is authorized.

6. Setting Up a Spring Boot REST API Project

Create a Spring Boot project with the Spring Web and Spring Security dependencies. The Spring Security starter provides the core security framework and its integration with Spring Boot.

6.1 Maven Dependencies

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

Use a Spring Boot version compatible with your Java version and allow its dependency management to select compatible Spring Security versions.

7. Creating a REST Controller

Before securing an API, create a controller with endpoints that return sample data. These endpoints will be used to demonstrate public and protected access.

package com.example.api;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api")
public class ApiController {

    @GetMapping("/public")
    public String publicEndpoint() {
        return "This endpoint is publicly accessible.";
    }

    @GetMapping("/user")
    public String userEndpoint() {
        return "Welcome to the protected user endpoint.";
    }

    @GetMapping("/admin")
    public String adminEndpoint() {
        return "Welcome to the administrator endpoint.";
    }
}

The controller defines three endpoints. The security configuration will determine which users can access each endpoint.

8. Configuring Spring Security for REST APIs

In modern Spring Security applications, security rules are commonly configured using a SecurityFilterChain bean. The following example uses HTTP Basic authentication to demonstrate endpoint protection. HTTP Basic is useful for learning and controlled testing, but production APIs should use an authentication architecture appropriate to their clients and threat model.

8.1 Security Configuration

package com.example.api.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(
            HttpSecurity http) throws Exception {

        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/public").permitAll()
                .requestMatchers("/api/admin").hasRole("ADMIN")
                .requestMatchers("/api/user").hasAnyRole(
                    "USER", "ADMIN")
                .anyRequest().authenticated()
            )
            .httpBasic(Customizer.withDefaults());

        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService(
            PasswordEncoder passwordEncoder) {

        UserDetails user = User.withUsername("apiuser")
            .password(passwordEncoder.encode("changeThisUserPassword"))
            .roles("USER")
            .build();

        UserDetails admin = User.withUsername("apiadmin")
            .password(passwordEncoder.encode("changeThisAdminPassword"))
            .roles("ADMIN")
            .build();

        return new InMemoryUserDetailsManager(user, admin);
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

Learning example: This configuration uses in-memory accounts and HTTP Basic authentication. Replace the example credentials and account storage before deployment. Never commit real credentials or use sample passwords in a production environment.

8.2 Explanation of the Configuration

  • @Configuration identifies a Spring configuration class.
  • SecurityFilterChain defines how HTTP requests are secured.
  • authorizeHttpRequests() specifies access rules for incoming requests.
  • requestMatchers() selects URL patterns.
  • permitAll() allows access without requiring authentication for the matching rule.
  • hasRole("ADMIN") restricts access to users with the ADMIN role.
  • hasAnyRole("USER", "ADMIN") permits users with either role.
  • authenticated() requires an authenticated identity.
  • httpBasic() enables HTTP Basic authentication.
  • BCryptPasswordEncoder provides password hashing and verification.

9. Understanding Role-Based API Authorization

Role-based authorization controls access according to a user's assigned role. For example, an application may define USER, ADMIN, and MANAGER roles.

Endpoint Required Access Purpose
/api/public Public General information.
/api/user USER or ADMIN Protected user functionality.
/api/admin ADMIN only Administrative functionality.

Spring Security's default role convention uses the ROLE_ prefix. When using hasRole("ADMIN"), the corresponding authority is normally ROLE_ADMIN. When using hasAuthority(), the exact authority value must match.

10. Securing APIs with JWT Authentication

JSON Web Tokens (JWTs) are commonly used to secure REST APIs. A client obtains an access token from an authentication or authorization service and sends it with subsequent API requests.

A JWT commonly contains claims such as the issuer, subject, expiration time, and optionally roles or scopes. The API must validate the token before trusting its claims.

10.1 Typical JWT Request Flow

  1. The client authenticates with an identity provider or authorization server.
  2. The authorization server issues an access token.
  3. The client sends the token in the HTTP Authorization header.
  4. Spring Security validates the token according to the configured trust settings.
  5. The application uses validated identity and authorization information to evaluate access rules.
  6. The API returns the protected resource when access is allowed.

A typical request includes the following header:

Authorization: Bearer <access-token>

The placeholder represents an access token issued for the application. Do not send real access tokens in public logs, screenshots, or source code repositories.

10.2 Add the OAuth2 Resource Server Dependency

For JWT-based API authentication, add the Spring Boot OAuth2 Resource Server starter. It provides resource-server integration; JWT decoding and signature validation also require the relevant JOSE support, which is brought in by the standard starter setup.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>

10.3 Configure JWT Validation

If an authorization server issues JWTs, configure the issuer URI supplied by that trusted provider.

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: https://idp.example.com/issuer

Replace the example URI with the actual issuer URI from the identity provider. The issuer must match the token's issuer claim, and the authorization server must provide the expected signing keys and metadata.

10.4 Configure a JWT-Protected API

package com.example.api.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.Customizer;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class JwtSecurityConfig {

    @Bean
    public SecurityFilterChain apiSecurityFilterChain(
            HttpSecurity http) throws Exception {

        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/public").permitAll()
                .requestMatchers("/api/admin/**")
                    .hasAuthority("SCOPE_api.admin")
                .anyRequest().authenticated()
            )
            .oauth2ResourceServer(oauth2 ->
                oauth2.jwt(Customizer.withDefaults())
            );

        return http.build();
    }
}

This example uses an authority convention such as SCOPE_api.admin for an authorization scope. The token must contain the appropriate scope, and Spring Security must map it to the expected authority. JWT scope mapping and role mapping are not interchangeable; configure the application according to the token claims and authorization server.

When configuring JWT authentication, the application should validate the token's signature, issuer, expiration, and other required claims. Merely decoding a JWT is not sufficient to trust it.

11. Understanding JWT Roles and Scopes

JWT access tokens can carry scopes or role information, depending on the identity provider and token design. Spring Security can convert recognized claims into authorities.

Concept Example Typical Use
Scope api.read Represents permission to access a defined API capability.
Role ROLE_ADMIN Represents a broad user responsibility.
Subject user-123 Identifies the token subject.
Issuer https://idp.example.com/issuer Identifies the trusted token issuer.
Expiration exp claim Defines when a token expires.

Do not assume that a token's custom role claim will automatically become a Spring Security role. If the provider uses a custom claim, configure a suitable authority converter and test the resulting authorities.

12. Understanding HTTP Status Codes in Secured APIs

REST APIs should return appropriate HTTP status codes when security checks fail.

Status Code Meaning Typical Security Scenario
200 OK Request succeeded. Authenticated user is permitted to read a resource.
201 Created A resource was created. Authorized user successfully creates a record.
400 Bad Request Request is invalid. Malformed or invalid input.
401 Unauthorized Authentication is missing or invalid. Missing or invalid credentials, depending on configuration.
403 Forbidden Access is not permitted. Authenticated user lacks required permission.
404 Not Found Resource was not found or is intentionally concealed. Requested resource is unavailable.

Although the status phrase is historically named “Unauthorized,” HTTP 401 is generally used for authentication challenges. HTTP 403 indicates that the server refuses the request. The exact response should follow the API's authentication mechanism and security design.

13. Configuring CORS for REST APIs

Cross-Origin Resource Sharing (CORS) is a browser security mechanism that controls whether frontend applications hosted on different origins can access an API. An origin includes the scheme, host, and port.

For example, a frontend hosted at https://app.example.com may need permission to call an API at https://api.example.com.

13.1 Example CORS Configuration

package com.example.api.config;

import java.util.List;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

@Configuration
public class CorsConfig {

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();

        configuration.setAllowedOrigins(
            List.of("https://app.example.com"));
        configuration.setAllowedMethods(
            List.of("GET", "POST", "PUT", "PATCH", "DELETE"));
        configuration.setAllowedHeaders(
            List.of("Authorization", "Content-Type"));
        configuration.setAllowCredentials(false);

        UrlBasedCorsConfigurationSource source =
            new UrlBasedCorsConfigurationSource();

        source.registerCorsConfiguration("/api/**", configuration);

        return source;
    }
}

Enable CORS handling in the relevant security chain with http.cors(Customizer.withDefaults()) when using this configuration source. Replace the sample frontend origin with the actual trusted origin.

If cookies or other browser-managed credentials are required, configure credential support carefully and specify explicit trusted origins. Do not combine credentialed CORS requests with a wildcard origin.

14. Understanding CSRF Protection

Cross-Site Request Forgery (CSRF) is relevant when browsers automatically attach authentication credentials, particularly session cookies. An attacker may attempt to trick a logged-in user's browser into sending an unwanted state-changing request.

Spring Security enables CSRF protection by default for common servlet-based configurations. Whether CSRF should remain enabled depends on the API's authentication mechanism and how clients send credentials.

When Should CSRF Be Considered?

  • Cookie or session-based authentication: CSRF protection is generally important for unsafe requests such as POST, PUT, PATCH, and DELETE.
  • Bearer tokens supplied explicitly by clients: CSRF exposure may differ when credentials are not automatically attached by the browser, but XSS and token-storage risks remain.
  • Mixed browser and API applications: Review the complete credential model before changing CSRF settings.

Do not disable CSRF protection simply because an endpoint is a REST API. Make the decision based on how authentication works and which clients access the API.

15. Password Hashing and Secure Credential Storage

Passwords should never be stored in plaintext. Spring Security provides the PasswordEncoder abstraction so applications can encode passwords during registration and verify submitted passwords during authentication.

15.1 BCrypt Password Encoder

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
public class PasswordConfig {

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

When a user registers, encode the password before storing it. During authentication, Spring Security compares the submitted password against the stored encoded value using the configured encoder.

For a production application, select and configure an appropriate password-hashing strategy for the application's security requirements. Never use reversible encryption or plaintext storage as a substitute for password hashing.

16. Protecting Sensitive Service Methods

Request-level security protects URL patterns, while method-level security protects business operations. Both can be useful because a service method may be invoked from multiple controllers or other application components.

16.1 Enable Method Security

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;

@Configuration
@EnableMethodSecurity
public class MethodSecurityConfig {
}

16.2 Apply Role Restrictions

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;

@Service
public class AccountService {

    @PreAuthorize("hasRole('ADMIN')")
    public String deleteAccount(Long accountId) {
        return "Account deletion requested for " + accountId;
    }

    @PreAuthorize("hasAnyRole('ADMIN', 'MANAGER')")
    public String viewAccountReport() {
        return "Account report generated.";
    }
}

The annotations above enforce role checks when these methods are invoked through Spring-managed security proxies. They do not replace resource ownership checks, validation, or business rules that the methods may also require.

17. Securing Resources and Checking Ownership

Role checks alone are not sufficient when users can access individual resources. An API should verify that the authenticated user has permission to access the specific resource requested.

For example, an endpoint such as GET /api/orders/125 should not return order 125 merely because the caller is authenticated. The service should check whether the order belongs to the current user or whether the user has an authorized administrative role.

Example Service Logic

public Order getOrderForUser(Long orderId, String username) {
    Order order = orderRepository.findById(orderId)
        .orElseThrow(() -> new OrderNotFoundException(
            "Order not found"));

    boolean isOwner = order.getCustomer()
        .getUsername().equals(username);

    if (!isOwner) {
        throw new AccessDeniedException(
            "You are not permitted to access this order");
    }

    return order;
}

This example illustrates an ownership check. A complete implementation should also handle authorized administrative access if required, avoid leaking sensitive resource information, and use suitable exception handling. The username must come from the authenticated server-side security context, not from an untrusted request parameter.

18. Adding Security Headers

HTTP security headers help browsers apply additional security restrictions. Spring Security provides support for common headers, including protections against content sniffing and frame-related attacks.

Security headers should be selected according to the application's architecture. For example, Content Security Policy (CSP) is often configured based on the scripts and resources a frontend actually needs.

http.headers(headers -> headers
    .contentTypeOptions(Customizer.withDefaults())
    .frameOptions(frame -> frame.deny())
);

Use headers that are compatible with the application. For example, denying framing is suitable for many applications, but embedded applications may require a more specific policy. Do not treat headers as a substitute for authentication, authorization, input validation, or secure transport.

19. Testing Secured REST APIs

Testing should verify both successful requests and security failures. A secured API should not only allow valid users but also consistently reject requests that lack the required credentials or permissions.

19.1 Test with Postman or a Similar API Client

  1. Start the Spring Boot application.
  2. Send a GET request to the public endpoint.
  3. Send a request to a protected endpoint without credentials.
  4. Repeat the request with valid credentials.
  5. Use a normal user to access the administrator endpoint.
  6. Verify that an administrator can access the administrator endpoint.
  7. Check the HTTP status code and response body for each request.

19.2 Example Requests

Public endpoint:

GET http://localhost:8080/api/public

Protected endpoint:

GET http://localhost:8080/api/user
Authorization: Basic <base64-encoded-credentials>

Administrator endpoint:

GET http://localhost:8080/api/admin
Authorization: Basic <base64-encoded-credentials>

For HTTP Basic authentication, API clients can encode credentials into the header automatically. Do not use real credentials over unencrypted HTTP outside a controlled local development environment.

19.3 Automated Testing with MockMvc

Spring Security's test support allows endpoint authorization to be tested without requiring a real login for every test. Add the Spring Security test dependency that matches the project's managed Spring Security version.

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.security.test.web.servlet.request
    .SecurityMockMvcRequestPostProcessors.user;
import static org.springframework.test.web.servlet.request
    .SecurityMockMvcRequestPostProcessors.csrf;
import static org.springframework.test.web.servlet.request
    .SecurityMockMvcRequestPostProcessors.httpBasic;
import static org.springframework.test.web.servlet.request
    .SecurityMockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result
    .MockMvcResultMatchers.status;

The static imports above illustrate the helpers available in Spring Security test support; use the request builders from org.springframework.test.web.servlet.request.MockMvcRequestBuilders in a complete test class.

@SpringBootTest
@AutoConfigureMockMvc
class ApiSecurityTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    void publicEndpointIsAccessible() throws Exception {
        mockMvc.perform(
                org.springframework.test.web.servlet.request
                    .MockMvcRequestBuilders.get("/api/public"))
            .andExpect(status().isOk());
    }

    @Test
    void userCannotAccessAdminEndpoint() throws Exception {
        mockMvc.perform(
                org.springframework.test.web.servlet.request
                    .MockMvcRequestBuilders.get("/api/admin")
                    .with(user("apiuser").roles("USER")))
            .andExpect(status().isForbidden());
    }

    @Test
    void adminCanAccessAdminEndpoint() throws Exception {
        mockMvc.perform(
                org.springframework.test.web.servlet.request
                    .MockMvcRequestBuilders.get("/api/admin")
                    .with(user("apiadmin").roles("ADMIN")))
            .andExpect(status().isOk());
    }
}

These tests demonstrate authorization behavior using mock authenticated users. They do not validate the application's real credential storage or JWT verification. Add integration tests for the actual authentication mechanism. The unauthenticated response may be 401 or a redirect depending on the configured authentication entry point.

20. Common REST API Security Problems

Problem Possible Cause Solution
Protected endpoint is accessible without credentials. The endpoint is matched by a public rule or falls under an unexpected configuration. Review matcher order and ensure protected paths require authentication.
Valid user receives HTTP 403. The user lacks the required role or authority. Inspect the granted authorities and configured access rules.
JWT is rejected. Invalid signature, expired token, incorrect issuer, or incorrect audience validation. Check token validity and the resource server's trust configuration.
JWT roles are not recognized. The roles claim is not mapped to Spring Security authorities. Configure and test the appropriate JWT authority converter.
Browser cannot call the API. CORS configuration does not permit the origin, method, or header. Configure CORS for the actual trusted frontend origin.
POST request fails with a CSRF error. A required CSRF token is missing or invalid. Send a valid CSRF token or review whether CSRF protection is appropriate for the authentication model.
Password authentication fails. The stored password hash and configured encoder do not match. Verify password encoding and the user-details configuration.
User can access another user's record. The API checks authentication but not resource ownership. Enforce ownership and object-level authorization in the service layer.

21. Best Practices for Securing REST APIs

  • Use HTTPS: encrypt API traffic in transit.
  • Choose an appropriate authentication mechanism: use an identity provider and OAuth 2.0 or OpenID Connect where appropriate for production systems.
  • Validate access tokens: verify signature, issuer, expiry, and other required claims.
  • Apply least privilege: grant only the roles and permissions required for each user or client.
  • Protect every sensitive endpoint: do not rely on frontend restrictions.
  • Check resource ownership: prevent users from accessing other users' data.
  • Use secure password hashing: never store plaintext passwords.
  • Configure CORS carefully: allow only required origins and methods.
  • Review CSRF protection: especially when browser-managed cookies authenticate requests.
  • Validate request data: use validation annotations, service-level checks, and parameterized database queries.
  • Protect secrets: keep passwords, signing keys, and client secrets out of source control and logs.
  • Handle errors safely: avoid exposing stack traces or internal implementation details.
  • Rate-limit sensitive operations: apply suitable protections against brute-force attempts and abuse.
  • Log security events: record relevant events while avoiding sensitive credentials and tokens.
  • Test authorization: include both allowed and denied access scenarios in automated tests.

22. Practical Project: Secure Employee REST API

Create an employee management API using Spring Boot and Spring Security. The goal is to protect employee records according to user roles and permissions.

Project Requirements

  • Create REST endpoints to list, retrieve, create, update, and delete employee records.
  • Implement authentication with an appropriate mechanism.
  • Define ADMIN, MANAGER, and USER roles.
  • Allow ADMIN users to manage all employee records.
  • Allow MANAGER users to access only approved management operations.
  • Allow USER accounts to view their own profile.
  • Use request-level authorization and method-level security where appropriate.
  • Validate request bodies and handle exceptions consistently.
  • Test unauthorized requests and forbidden operations.
  • Document endpoints, authentication requirements, and expected response codes.

Suggested Endpoint Design

HTTP Method Endpoint Access Rule Purpose
GET /api/employees ADMIN or MANAGER List employees.
GET /api/employees/{id} Authorized employee access Retrieve a specific employee.
POST /api/employees ADMIN or MANAGER Create an employee.
PUT /api/employees/{id} ADMIN or permitted MANAGER Update an employee.
DELETE /api/employees/{id} ADMIN Delete an employee.
GET /api/profile Authenticated user View the current user's profile.

For endpoints that operate on individual employees, include object-level authorization checks in addition to role checks. The exact policy should reflect the application's business requirements.

23. Interview Questions and Answers

Q1. What is Spring Security?

Spring Security is a framework for implementing authentication, authorization, and other security protections in Spring applications.

Q2. How do you secure REST APIs in Spring Boot?

Configure a SecurityFilterChain, define authentication and authorization rules, validate credentials or access tokens, and apply appropriate protections such as CSRF handling, CORS configuration, and secure password storage.

Q3. What is the difference between HTTP 401 and HTTP 403?

HTTP 401 generally indicates that valid authentication is missing or has failed. HTTP 403 indicates that the request is not permitted under the applicable authorization rules.

Q4. What is JWT authentication?

JWT authentication uses a JSON Web Token as a credential. A resource server validates the token and uses trusted claims to establish identity and evaluate authorization.

Q5. What is the Authorization header?

It is an HTTP header used to send authentication credentials. Examples include Basic credentials and Bearer access tokens.

Q6. What is the purpose of SecurityFilterChain?

It defines the security filters and request-processing rules that apply to matching HTTP requests.

Q7. What is the difference between roles and authorities?

A role usually represents a broad category of access, while an authority is a granted security value that can represent a role or a more specific permission.

Q8. What is CORS?

CORS is a browser mechanism that controls whether a webpage from one origin can access resources from another origin. It does not replace API authentication.

Q9. When is CSRF protection important?

It is particularly important when browsers automatically attach authentication credentials, such as session cookies, to requests. The correct configuration depends on the authentication model.

Q10. Why is HTTPS necessary?

HTTPS encrypts communication between clients and servers, helping protect credentials, access tokens, and application data in transit.

Q11. How should passwords be stored?

Passwords should be stored using an appropriate password-hashing algorithm through a configured PasswordEncoder, never as plaintext.

Q12. Why are resource ownership checks necessary?

Role checks alone may not stop one user from accessing another user's data. Ownership checks ensure that the caller is authorized to access the particular resource.

24. Quick Revision Checklist

  • REST APIs use HTTP methods to expose application resources.
  • Authentication verifies identity; authorization checks access permissions.
  • SecurityFilterChain configures request security.
  • hasRole() and hasAuthority() can restrict endpoint access.
  • JWT-based APIs commonly use Spring Security OAuth2 Resource Server support.
  • JWT validation must include appropriate trust and expiry checks.
  • CSRF and CORS address different security concerns.
  • Passwords must be securely hashed.
  • Use HTTP 401 and 403 appropriately for authentication and authorization failures.
  • Verify resource ownership for user-specific records.
  • Test both successful and rejected requests.
  • Use HTTPS and follow the principle of least privilege.

25. Conclusion

Securing REST APIs using Spring Security is an essential skill for Java backend developers. Spring Security provides the components needed to enforce authentication, role-based authorization, token validation, and additional request protections in Spring Boot applications.

A secure API requires more than adding a security dependency. Developers must carefully configure access rules, validate credentials and tokens, protect sensitive resources, manage password storage, and test failure scenarios. Applying these practices helps create reliable APIs for web applications, mobile clients, and distributed systems.

To continue learning, explore the Advance Java Training course, register for a course demo, or visit the JustAcademy website.

26. Additional Learning Resources

Previous Next
whatsapp